package cn.wch.ch934xlib.connet;

import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbRequest;

import androidx.annotation.NonNull;

import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Locale;

import cn.wch.ch934xlib.utils.LogUtil;


public class UsbRequestPool implements IUsbRequestPool{

    private static UsbRequestPool usbRequestPool;

    public static UsbRequestPool getInstance() {
        if(usbRequestPool==null){
            synchronized (UsbRequestPool.class){
                usbRequestPool=new UsbRequestPool();
            }
        }
        return usbRequestPool;
    }
    private HashMap<UsbEndpoint,UsbRequest> requestHashMap;
    private HashMap<UsbRequest,ByteBuffer> bufferHashMap;

    public UsbRequestPool() {
        requestHashMap=new HashMap<>();
        bufferHashMap=new HashMap<>();
    }

    public void init(@NonNull UsbDeviceConnection usbDeviceConnection, @NonNull UsbEndpoint usbEndpoint){
        int maxPacketSize = usbEndpoint.getMaxPacketSize();
        ByteBuffer byteBuffer=ByteBuffer.allocate(maxPacketSize);
        UsbRequest request=new UsbRequest();
        request.initialize(usbDeviceConnection,usbEndpoint);
        requestHashMap.put(usbEndpoint,request);
        bufferHashMap.put(request, byteBuffer);
        queue(usbEndpoint);
    }

    public void queue(@NonNull UsbEndpoint usbEndpoint){
        UsbRequest usbRequest = getUsbRequest(usbEndpoint);
        if(usbRequest==null){
            return;
        }
        ByteBuffer byteBuffer = bufferHashMap.get(usbRequest);
        if(byteBuffer==null){
            return;
        }
        byteBuffer.clear();
        usbRequest.queue(byteBuffer,byteBuffer.capacity());
    }

    public UsbRequest getUsbRequest(@NonNull UsbEndpoint usbEndpoint){
        return requestHashMap.get(usbEndpoint);
    }

    public ByteBuffer getBuffer(@NonNull UsbEndpoint usbEndpoint){
        UsbRequest usbRequest = getUsbRequest(usbEndpoint);
        if(usbRequest==null){
            return null;
        }
        return bufferHashMap.get(usbRequest);
    }

    public void stop(@NonNull UsbEndpoint usbEndpoint){
        LogUtil.d(String.format(Locale.getDefault(),"UsbEndpoint %d stop",usbEndpoint.getEndpointNumber()));
        UsbRequest usbRequest = getUsbRequest(usbEndpoint);
        if(usbRequest==null){
            return;
        }
        usbRequest.cancel();
        clear(usbEndpoint);
    }

    private void clear(@NonNull UsbEndpoint usbEndpoint){
        UsbRequest usbRequest = getUsbRequest(usbEndpoint);
        if(usbRequest!=null){
            bufferHashMap.remove(usbRequest);
        }
        requestHashMap.remove(usbEndpoint);
    }

}
